package auctionhaus

import org.springframework.dao.DataIntegrityViolationException
import groovy.xml.MarkupBuilder

class CustomerController {
    // require that the user is logged in before allowing all actions requiring logging in
    def beforeInterceptor = [action:this.&isUserLoggedIn,except:
            ['index','list','show','save','login','doLogin','logout']]

    def customerService = new CustomerService()
    static allowedMethods = [save: "POST", update: "POST", delete: "POST"]

    def index() {
        redirect(action: "list", params: params)
    }

    def list() {
        params.max = Math.min(params.max ? params.int('max') : 10, 100)
        [customerInstanceList: Customer.list(params), customerInstanceTotal: Customer.count()]
    }

    def create() {
        [customerInstance: new Customer(params)]
    }

    def save() {
        //def customerInstance = new Customer(params)
        def customerInstance = customerService.addCustomer(params["email"], params["password"])
        if (!customerInstance.save(flush: true)) {
            render(view: "create", model: [customerInstance: customerInstance])
            return
        }

		flash.message = message(code: 'default.created.message', args: [message(code: 'customer.label', default: 'Customer'), customerInstance.id])
        redirect(action: "show", id: customerInstance.id)
    }

    def show() {
        def customerInstance = Customer.get(params.id)
        if (!customerInstance) {
			flash.message = message(code: 'default.not.found.message', args: [message(code: 'customer.label', default: 'Customer'), params.id])
            redirect(action: "list")
            return
        }

        [customerInstance: customerInstance]
    }

    def edit() {
        def customerInstance = Customer.get(params.id)
        if (!customerInstance) {
            flash.message = message(code: 'default.not.found.message', args: [message(code: 'customer.label', default: 'Customer'), params.id])
            redirect(action: "list")
            return
        }

        [customerInstance: customerInstance]
    }

    def update() {
        def customerInstance = Customer.get(params.id)
        if (!customerInstance) {
            flash.message = message(code: 'default.not.found.message', args: [message(code: 'customer.label', default: 'Customer'), params.id])
            redirect(action: "list")
            return
        }

        if (params.version) {
            def version = params.version.toLong()
            if (customerInstance.version > version) {
                customerInstance.errors.rejectValue("version", "default.optimistic.locking.failure",
                          [message(code: 'customer.label', default: 'Customer')] as Object[],
                          "Another user has updated this Customer while you were editing")
                render(view: "edit", model: [customerInstance: customerInstance])
                return
            }
        }

        customerInstance.properties = params

        if (!customerInstance.save(flush: true)) {
            render(view: "edit", model: [customerInstance: customerInstance])
            return
        }

		flash.message = message(code: 'default.updated.message', args: [message(code: 'customer.label', default: 'Customer'), customerInstance.id])
        redirect(action: "show", id: customerInstance.id)
    }

    def delete() {
        def customerInstance = Customer.get(params.id)
        if (!customerInstance) {
			flash.message = message(code: 'default.not.found.message', args: [message(code: 'customer.label', default: 'Customer'), params.id])
            redirect(action: "list")
            return
        }

        try {
            if (hasNoBids(customerInstance) && hasNoListings(customerInstance)) {
                customerInstance.delete(flush: true)
			    flash.message = message(code: 'default.deleted.message', args: [message(code: 'customer.label', default: 'Customer'), params.id])
                redirect(action: "list")
            }
            else {
                flash.message = "The customer must have 0 bids and 0 listings before they can be deleted."
                redirect action:"list"
            }
        }
        catch (DataIntegrityViolationException e) {
			flash.message = message(code: 'default.not.deleted.message', args: [message(code: 'customer.label', default: 'Customer'), params.id])
            redirect(action: "show", id: params.id)
        }
    }

    // log the user out
    def logout = {
        // clear out the name of the logged in user
        session.customerLoggedIn = ""

        flash.message = "You have logged out."
        redirect(action: "login", id: params.id)
    }

    // provide user with login form
    def login = {
        [customerInstance: new Customer(params)]
    }

    // try to login with given email and password
    def doLogin = {
        def newCustomer = Customer.findWhere(email:params['email'],
                password:params['password'])

        // set our session variable to the user that logged in
        session.customerLoggedIn = newCustomer.email
        session.customerLoggedInId = newCustomer.id

        if (newCustomer) { // login successful
            flash.message = "Nice! Login successful!"
            redirect(controller:'customer',action:'list')
        }
        else { // login unsuccessful
            flash.message = "Username or password incorrect...  please try that again."
            redirect(controller:'customer',action:'login')
        }
    }

    // make sure customer exists before we delete it
    private def withCustomer(id="id", Closure c) {
        int custId = Integer.parseInt(params[id].toString())
        def customer = Customer.get(custId)

        if(customer) {
            c.call customer
        } else {
            // go back to the customer list
            flash.message = "The customer was not found."
            redirect action:"list"
        }
    }

    // returns true if customer has no bids, false otherwise
    private def hasNoBids(def custo) {
        // query for bids of the customer
        def bidOfCustomer = Bid.findByBidder(custo)

        if( bidOfCustomer ) {
            return false
        } else {
            return true
        }
    }

    // returns true if customer has no listings, false otherwise
    private def hasNoListings(def custo) {
        // query for listings of the customer
        def listingOfCustomer = Listing.findBySeller(custo)

        if( listingOfCustomer ) {
            return false
        } else {
            return true
        }
    }

    // checks whether the user is logged in
    def isUserLoggedIn() {
        if(session.customerLoggedIn) { // logged in

            if( !(Customer.findWhere(email:session.customerLoggedIn).role == "admin") ){ // this user is NOT an admin
                flash.message = "Requires admin priviledges."
                redirect(action:"login")

                return false
            }

            return true
        }
        else { // NOT logged in
            flash.message = "Must be logged in."
            redirect action:"login"
            return false
        }
    }
}
